package com.jiashihui.server1.utils;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * HTTP工具类
 */
public class HttpUtils {
    /**
     * 定义编码格式 UTF-8
     */

    public static final String CHARSET_UTF8 = "UTF-8";
    public static final String ERROR_LOG = "Error content:";
    private static final String URL_PARAM_CONNECT_FLAG = "&";
    private static final String EMPTY = "";
    private static final Log LOGGER = LogFactory.getLog(HttpUtils.class);
    private static MultiThreadedHttpConnectionManager connectionManager;
    /**
     * 连接超时
     */
    private static final int CONNECTIONTIMEOUT = 500;
    /**
     * socket超时
     */
    private static final int SOCKETTIMEOUT = 7000;
    private static final int MAXCONNECTIONPERHOST = 1000;
    private static final int MAXTOTALCONNECTIONS = 1000;
    private static HttpClient client;
    static {
        connectionManager = new MultiThreadedHttpConnectionManager();
        connectionManager.getParams().setConnectionTimeout(CONNECTIONTIMEOUT);
        connectionManager.getParams().setSoTimeout(SOCKETTIMEOUT);
        connectionManager.getParams().setDefaultMaxConnectionsPerHost(MAXCONNECTIONPERHOST);
        connectionManager.getParams().setMaxTotalConnections(MAXTOTALCONNECTIONS);
        connectionManager.getParams().setTcpNoDelay(true);
    }

    public static String urlPost(String url, String jsonbody) {
        return urlPost(url, jsonbody, null);
    }

    /**
     * POST方式提交数据
     *
     * @param url
     *            待请求的URL
     * @param jsonbody
     *            要提交的数据
     * @param token
     *            新token
     * @return 响应结果
     * @throws IOException
     *             IO异常
     */
    public static String urlPost(String url, String jsonbody, String token) {
        client = new HttpClient(connectionManager);
        String response = EMPTY;
        PostMethod postMethod = null;
        try {
            postMethod = new PostMethod(url);
            postMethod.setRequestHeader("Content-Type", "application/json;charset=" + CHARSET_UTF8);
            if (token != null) {
                postMethod.setRequestHeader("Authorization", "Bearer " + token);
            }
            // 将表单的值放入postMethod中
            postMethod.setRequestBody(jsonbody);
            // 执行postMethod
            int statusCode = client.executeMethod(postMethod);
            if (statusCode == HttpStatus.SC_OK) {
                response = postMethod.getResponseBodyAsString();
            } else {
                LOGGER.error("响应状态码 = " + postMethod.getStatusCode());
            }
        } catch (HttpException e) {
            LOGGER.error("发生致命的异常，可能是协议不对或者返回的内容有问题", e);
        } catch (IOException e) {
            LOGGER.error("发生网络异常", e);
        } finally {
            if (postMethod != null) {
                postMethod.releaseConnection();
                postMethod = null;
            }
        }
        return response;
    }

    /**
     * GET
     * @param url
     * @param params
     * @return
     */
    public static String urlGet(String url, Map<String, String> params) {
        return urlGet(url, params, null);
    }

    /**
     * GET方式提交数据
     *
     * @param url
     *            待请求的URL
     * @param params
     *            要提交的数据
     * @param token
     *            编码 token
     * @return 响应结果
     * @throws IOException
     *             IO异常
     */
    public static String urlGet(String url, Map<String, String> params, String token) {
        client = new HttpClient(connectionManager);
        String response = EMPTY;
        GetMethod getMethod = null;
        StringBuilder strtTotalURL = new StringBuilder(EMPTY);
        if (strtTotalURL.indexOf("?") == -1) {
            strtTotalURL.append(url).append("?").append(getUrl(params, CHARSET_UTF8));
        } else {
            strtTotalURL.append(url).append("&").append(getUrl(params, CHARSET_UTF8));
        }
        LOGGER.debug("GET请求URL = \n" + strtTotalURL.toString());
        try {
            getMethod = new GetMethod(strtTotalURL.toString());
            getMethod.setRequestHeader("Content-Type", "application/json;charset=" + CHARSET_UTF8);
            if (token != null) {
                getMethod.setRequestHeader("Authorization", "Bearer " + token);
            }
            // 执行getMethod
            int statusCode = client.executeMethod(getMethod);
            if (statusCode == HttpStatus.SC_OK) {
                response = getMethod.getResponseBodyAsString();
            } else {
                LOGGER.error("响应状态码 = " + getMethod.getStatusCode());
                LOGGER.error("响应状态结果 = " + getMethod.getResponseBodyAsString());
            }
        } catch (HttpException e) {
            LOGGER.error("发生致命的异常，可能是协议不对或者返回的内容有问题", e);
        } catch (IOException e) {
            LOGGER.error("发生网络异常", e);
        } finally {
            if (getMethod != null) {
                getMethod.releaseConnection();
                getMethod = null;
            }
        }
        return response;
    }

    /**
     * 据Map生成URL字符串
     *
     * @param map
     *            Map
     * @param valueEnc
     *            URL编码
     * @return URL
     */
    private static String getUrl(Map<String, String> map, String valueEnc) {
        client = new HttpClient(connectionManager);
        if (null == map || map.keySet().isEmpty()) {
            return (EMPTY);
        }
        StringBuilder url = new StringBuilder();
        Set<String> keys = map.keySet();
        for (Iterator<String> it = keys.iterator(); it.hasNext(); ) {
            String key = it.next();
            if (map.containsKey(key)) {
                String val = map.get(key);
                String str = val != null ? val : EMPTY;
                try {
                    str = URLEncoder.encode(str, valueEnc);
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error("不支持的编码格式", e);
                }
                url.append(key).append("=").append(str).append(URL_PARAM_CONNECT_FLAG);
            }
        }
        String strURL;
        strURL = url.toString();
        if (URL_PARAM_CONNECT_FLAG.equals(EMPTY + strURL.charAt(strURL.length() - 1))) {
            strURL = strURL.substring(0, strURL.length() - 1);
        }
        return (strURL);
    }

    public static String doPostInfo(String url, Map<String, Object> paramMap) {
        // 获取输入流
        client = new HttpClient(connectionManager);
        InputStream is = null;
        BufferedReader br = null;
        String result = null;
        PostMethod postMethod = new PostMethod(url);
        NameValuePair[] nvp = null;
        // 判断参数map集合paramMap是否为空
        if (null != paramMap && paramMap.size() > 0) {
            // // 不为空
            // 创建键值参数对象数组，大小为参数的个数
            nvp = new NameValuePair[paramMap.size()];
            // 循环遍历参数集合map
            Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
            // 获取迭代器
            Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
            int index = 0;
            while (iterator.hasNext()) {
                Map.Entry<String, Object> mapEntry = iterator.next();
                // 从mapEntry中获取key和value创建键值对象存放到数组中
                try {
                    nvp[index] = new NameValuePair(mapEntry.getKey(), new String(mapEntry.getValue().toString().getBytes(HttpUtils.CHARSET_UTF8), HttpUtils.CHARSET_UTF8));
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error(HttpUtils.ERROR_LOG, e);
                }
                index++;
            }
        }
        // 判断nvp数组是否为空
        if (null != nvp && nvp.length > 0) {
            // 将参数存放到requestBody对象中
            postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
            postMethod.setRequestBody(nvp);
        }
        // 执行POST方法
        try {
            int statusCode = client.executeMethod(postMethod);
            // 判断是否成功
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method faild: " + postMethod.getStatusLine());
            }
            // 获取远程返回的数据
            is = postMethod.getResponseBodyAsStream();
            // 封装输入流
            br = new BufferedReader(new InputStreamReader(is, HttpUtils.CHARSET_UTF8));
            StringBuffer sbf = new StringBuffer();
            String temp = null;
            while ((temp = br.readLine()) != null) {
                sbf.append(temp).append("\r\n");
            }
            result = sbf.toString();
        } catch (IOException e) {
            LOGGER.error(HttpUtils.ERROR_LOG, e);
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(HttpUtils.ERROR_LOG, e);
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error(HttpUtils.ERROR_LOG, e);
                }
            }
            // 释放连接
            postMethod.releaseConnection();
        }
        return result;
    }

//    public static void main(String[] args) {
//        Map<String, Object> params = new HashMap<>();
//        JSONObject jObject = new JSONObject();
//        jObject.put("siteId", "KT57704999");
//        jObject.put("dataType", "A");
//        params.put("params", jObject);
//        params.put("factoryCode", "F003");
//        params.put("timestamp", 1543921200003L);
//        params.put("digest", "ZWJiYzU3NjFjMmM1YzFkOTI2ZjA4NmZjNWU4ZmFiNGI=");
//        String aa = HttpUtils.doPostInfo("http://localhost:8899/.....", params);
//    }
}
